#!/usr/bin/env python3
"""
日志记录模块

本模块负责配置和管理应用程序的日志记录功能。
主要功能包括：
- 结构化日志记录
- 多级别日志支持
- 性能统计记录
- 错误追踪
- 日志格式化
"""

import os
import sys
import logging
import logging.config
import time
from functools import wraps
from pathlib import Path
from typing import Optional, Dict, Any, Union
from datetime import datetime

import structlog
from structlog.stdlib import LoggerFactory


# 全局日志配置
LOG_LEVEL_MAP = {
    'DEBUG': logging.DEBUG,
    'INFO': logging.INFO,
    'WARNING': logging.WARNING,
    'ERROR': logging.ERROR,
    'CRITICAL': logging.CRITICAL,
}


def setup_logger(log_level: str = 'INFO', enable_json: bool = False) -> None:
    """
    设置全局日志配置
    
    配置 structlog 和标准库 logging，支持结构化日志和性能监控。
    
    Args:
        log_level: 日志级别 (DEBUG, INFO, WARNING, ERROR, CRITICAL)
        enable_json: 是否启用 JSON 格式输出
    """
    # 配置标准库 logging
    logging.basicConfig(
        level=LOG_LEVEL_MAP.get(log_level.upper(), logging.INFO),
        format="%(message)s",
        stream=sys.stdout,
    )
    
    # 配置 structlog 处理器
    processors = [
        structlog.stdlib.filter_by_level,
        structlog.stdlib.add_logger_name,
        structlog.stdlib.add_log_level,
        structlog.stdlib.PositionalArgumentsFormatter(),
        structlog.processors.TimeStamper(fmt="%Y-%m-%d %H:%M:%S"),
        structlog.processors.StackInfoRenderer(),
        structlog.processors.format_exc_info,
    ]
    
    if enable_json:
        # JSON 格式输出（适用于生产环境）
        processors.append(structlog.processors.JSONRenderer())
    else:
        # 人类可读格式（适用于开发环境）
        processors.append(
            structlog.dev.ConsoleRenderer(
                colors=True,
                exception_formatter=structlog.dev.plain_traceback,
            )
        )
    
    # 配置 structlog
    structlog.configure(
        processors=processors,
        wrapper_class=structlog.stdlib.BoundLogger,
        logger_factory=LoggerFactory(),
        cache_logger_on_first_use=True,
    )


def get_logger(name: str) -> structlog.stdlib.BoundLogger:
    """
    获取结构化日志记录器
    
    Args:
        name: 日志记录器名称，通常使用 __name__
        
    Returns:
        structlog.stdlib.BoundLogger: 结构化日志记录器实例
    """
    return structlog.get_logger(name)


class PerformanceLogger:
    """
    性能监控日志记录器
    
    专门用于记录性能相关的指标，包括执行时间、资源使用情况等。
    """
    
    def __init__(self, logger_name: str = "performance"):
        """
        初始化性能日志记录器
        
        Args:
            logger_name: 日志记录器名称
        """
        self.logger = get_logger(logger_name)
        self.start_times: Dict[str, float] = {}
    
    def start_timer(self, operation: str) -> None:
        """
        开始计时
        
        Args:
            operation: 操作名称
        """
        self.start_times[operation] = time.time()
        self.logger.debug("操作开始", operation=operation)
    
    def end_timer(self, operation: str, **kwargs) -> float:
        """
        结束计时并记录性能数据
        
        Args:
            operation: 操作名称
            **kwargs: 额外的上下文信息
            
        Returns:
            float: 执行时间（秒）
        """
        if operation not in self.start_times:
            self.logger.warning("未找到对应的开始时间", operation=operation)
            return 0.0
        
        execution_time = time.time() - self.start_times[operation]
        del self.start_times[operation]
        
        self.logger.info(
            "操作完成",
            operation=operation,
            execution_time=execution_time,
            **kwargs
        )
        
        return execution_time
    
    def log_query_performance(self, query: str, execution_time: float, 
                            result_count: int = 0, **kwargs) -> None:
        """
        记录查询性能数据
        
        Args:
            query: SQL 查询语句
            execution_time: 执行时间（秒）
            result_count: 结果数量
            **kwargs: 额外的上下文信息
        """
        # 截断长查询以避免日志过长
        max_query_length = int(os.getenv('MCP_MAX_QUERY_LENGTH', '1000'))
        truncated_query = query[:max_query_length]
        if len(query) > max_query_length:
            truncated_query += "..."
        
        self.logger.info(
            "SQL查询执行",
            query=truncated_query,
            execution_time=execution_time,
            result_count=result_count,
            **kwargs
        )
    
    def log_connection_event(self, event_type: str, **kwargs) -> None:
        """
        记录连接相关事件
        
        Args:
            event_type: 事件类型 (connect, disconnect, error, etc.)
            **kwargs: 事件相关信息
        """
        self.logger.info(
            "数据库连接事件",
            event_type=event_type,
            timestamp=datetime.now().isoformat(),
            **kwargs
        )


class MCPLogger:
    """
    MCP 协议专用日志记录器
    
    专门用于记录 MCP 协议相关的操作和事件。
    """
    
    def __init__(self, logger_name: str = "mcp"):
        """
        初始化 MCP 日志记录器
        
        Args:
            logger_name: 日志记录器名称
        """
        self.logger = get_logger(logger_name)
        self.enable_query_logging = os.getenv('MCP_ENABLE_QUERY_LOGGING', 'true').lower() == 'true'
    
    def log_request(self, method: str, params: Optional[Dict[str, Any]] = None, 
                   request_id: Optional[str] = None) -> None:
        """
        记录 MCP 请求
        
        Args:
            method: MCP 方法名
            params: 请求参数
            request_id: 请求 ID
        """
        if self.enable_query_logging:
            self.logger.info(
                "MCP请求",
                method=method,
                params=params,
                request_id=request_id,
                timestamp=datetime.now().isoformat()
            )
    
    def log_response(self, method: str, success: bool, 
                    result: Optional[Any] = None, error: Optional[str] = None,
                    request_id: Optional[str] = None, execution_time: Optional[float] = None) -> None:
        """
        记录 MCP 响应
        
        Args:
            method: MCP 方法名
            success: 是否成功
            result: 响应结果
            error: 错误信息
            request_id: 请求 ID
            execution_time: 执行时间
        """
        log_data = {
            "method": method,
            "success": success,
            "request_id": request_id,
            "timestamp": datetime.now().isoformat()
        }
        
        if execution_time is not None:
            log_data["execution_time"] = execution_time
        
        if success:
            if self.enable_query_logging and result is not None:
                # 对于大型结果，只记录摘要信息
                if isinstance(result, list):
                    log_data["result_count"] = len(result)
                else:
                    log_data["result_type"] = type(result).__name__
            
            self.logger.info("MCP响应成功", **log_data)
        else:
            log_data["error"] = error
            self.logger.error("MCP响应失败", **log_data)
    
    def log_server_event(self, event_type: str, **kwargs) -> None:
        """
        记录服务器事件
        
        Args:
            event_type: 事件类型 (startup, shutdown, error, etc.)
            **kwargs: 事件相关信息
        """
        self.logger.info(
            "MCP服务器事件",
            event_type=event_type,
            timestamp=datetime.now().isoformat(),
            **kwargs
        )


def log_execution_time(logger: Optional[structlog.stdlib.BoundLogger] = None):
    """
    装饰器：记录函数执行时间
    
    Args:
        logger: 可选的日志记录器，如果不提供则使用默认记录器
        
    Returns:
        装饰器函数
    """
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            func_logger = logger or get_logger(func.__module__)
            
            try:
                result = func(*args, **kwargs)
                execution_time = time.time() - start_time
                
                func_logger.debug(
                    "函数执行完成",
                    function=func.__name__,
                    execution_time=execution_time,
                    success=True
                )
                
                return result
                
            except Exception as e:
                execution_time = time.time() - start_time
                
                func_logger.error(
                    "函数执行失败",
                    function=func.__name__,
                    execution_time=execution_time,
                    error=str(e),
                    success=False
                )
                
                raise
        
        return wrapper
    return decorator


# 初始化默认日志配置
def _initialize_default_logging():
    """
    初始化默认日志配置
    
    根据环境变量设置默认的日志级别和格式。
    """
    log_level = os.getenv('MCP_LOG_LEVEL', 'INFO')
    enable_json = os.getenv('MCP_LOG_FORMAT', 'console').lower() == 'json'
    
    setup_logger(log_level, enable_json)


# 模块加载时自动初始化日志
_initialize_default_logging()


def log_database_connection(host: str, port: int, database: str, user: str) -> None:
    """
    记录数据库连接尝试
    
    Args:
        host: 数据库主机
        port: 数据库端口
        database: 数据库名称
        user: 用户名
    """
    logger = get_logger("database")
    logger.info(
        "尝试连接数据库",
        host=host,
        port=port,
        database=database,
        user=user
    )


def log_database_connection_success(connection_time: float) -> None:
    """
    记录数据库连接成功
    
    Args:
        connection_time: 连接耗时
    """
    logger = get_logger("database")
    logger.info(
        "数据库连接成功",
        connection_time=connection_time
    )


def log_database_connection_error(error: Exception) -> None:
    """
    记录数据库连接错误
    
    Args:
        error: 错误信息
    """
    logger = get_logger("database")
    logger.error(
        "数据库连接失败",
        error=str(error),
        error_type=type(error).__name__
    )


def log_query_execution(query: str, params: Any = None) -> None:
    """
    记录查询执行
    
    Args:
        query: SQL查询语句
        params: 查询参数
    """
    logger = get_logger("database")
    # 截断长查询以避免日志过长
    max_query_length = int(os.getenv('MCP_MAX_QUERY_LENGTH', '1000'))
    truncated_query = query[:max_query_length]
    if len(query) > max_query_length:
        truncated_query += "..."
    
    logger.debug(
        "执行SQL查询",
        query=truncated_query,
        has_params=params is not None
    )


def log_query_result(query: str, row_count: int, execution_time: float) -> None:
    """
    记录查询结果
    
    Args:
        query: SQL查询语句
        row_count: 结果行数
        execution_time: 执行时间
    """
    logger = get_logger("database")
    # 截断长查询以避免日志过长
    max_query_length = int(os.getenv('MCP_MAX_QUERY_LENGTH', '1000'))
    truncated_query = query[:max_query_length]
    if len(query) > max_query_length:
        truncated_query += "..."
    
    logger.info(
        "查询执行完成",
        query=truncated_query,
        row_count=row_count,
        execution_time=execution_time
    )


def log_query_error(query: str, error: Exception) -> None:
    """
    记录查询错误
    
    Args:
        query: SQL查询语句
        error: 错误信息
    """
    logger = get_logger("database")
    # 截断长查询以避免日志过长
    max_query_length = int(os.getenv('MCP_MAX_QUERY_LENGTH', '1000'))
    truncated_query = query[:max_query_length]
    if len(query) > max_query_length:
        truncated_query += "..."
    
    logger.error(
        "查询执行失败",
        query=truncated_query,
        error=str(error),
        error_type=type(error).__name__
    )


def log_mcp_server_start(host: str, port: int) -> None:
    """
    记录MCP服务器启动
    
    Args:
        host: 服务器主机
        port: 服务器端口
    """
    logger = get_logger("mcp_server")
    logger.info(
        "MCP服务器启动",
        host=host,
        port=port
    )


def log_mcp_server_stop() -> None:
    """
    记录MCP服务器停止
    """
    logger = get_logger("mcp_server")
    logger.info("MCP服务器停止")


def log_mcp_request(method: str, params: Any = None) -> None:
    """
    记录MCP请求
    
    Args:
        method: 请求方法
        params: 请求参数
    """
    logger = get_logger("mcp_server")
    logger.debug(
        "收到MCP请求",
        method=method,
        has_params=params is not None
    )


def log_mcp_response(method: str, success: bool, response_time: float) -> None:
    """
    记录MCP响应
    
    Args:
        method: 请求方法
        success: 是否成功
        response_time: 响应时间
    """
    logger = get_logger("mcp_server")
    if success:
        logger.info(
            "MCP请求处理完成",
            method=method,
            response_time=response_time
        )
    else:
        logger.error(
            "MCP请求处理失败",
            method=method,
            response_time=response_time
        )


def log_config_loaded(config_dict: Dict[str, Any]) -> None:
    """
    记录配置加载
    
    Args:
        config_dict: 配置字典
    """
    logger = get_logger("config")
    logger.info(
        "配置加载完成",
        config_keys=list(config_dict.keys())
    )


# 导出常用的日志记录器实例
performance_logger = PerformanceLogger()
mcp_logger = MCPLogger()